package top.humbleyuan.annotation_skill.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import top.humbleyuan.annotation_skill.annotation.SysLog;

import java.lang.reflect.Method;

/**
 * @Author HumbleYuan
 * @Date 2019/11/25 9:36
 * @Des 日志注解切面
 */
@Component("sysLogAspect")
@Aspect
public class SysLogAspect {

    // 切入点
    @Pointcut("@annotation(top.humbleyuan.annotation_skill.annotation.SysLog)")
    public void logPointCut() {
    }

    // 环绕切面
    @Around("logPointCut() && @annotation(sysLog)")
    public Object around(ProceedingJoinPoint point, SysLog sysLog) throws Throwable {

        long beginTime = System.currentTimeMillis();

        // 执行方法
        Object result = point.proceed();

        // 记录执行时间
        long duration = System.currentTimeMillis() - beginTime;

        // 输出执行日志
        logOut(point, duration);

        return result;
    }

    // 输出执行日志
    private void logOut(ProceedingJoinPoint point, long duration) {
        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Method method = methodSignature.getMethod();

        StringBuilder log = new StringBuilder(duration + "ms ");

        // 类名.方法名
        log.append(point.getTarget().getClass().getName() + ".")
                .append(methodSignature.getName());

        // log信息
        String logValue = "";
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if(sysLog != null) {
            // 注解描述
            logValue = sysLog.value();
        }

        log.append(":" + logValue);
        System.out.println(log.toString());
    }
}
